ci(release): add automated npm publishing with OIDC trusted publishing#170
ci(release): add automated npm publishing with OIDC trusted publishing#170backnotprop merged 1 commit intobacknotprop:mainfrom
Conversation
|
Ty for this, I'm flying back home and will review a bit later today |
Adds an npm-publish job to the release workflow that publishes @plannotator/opencode and @plannotator/pi-extension to npm with OIDC trusted publishing and provenance attestation. - Add pull_request and workflow_dispatch triggers (with dry-run input) - Derive DRY_RUN env var; publish only on tag pushes or explicit opt-in - Pin all action refs to SHA for supply-chain security - Gate the release job on tag refs to avoid spurious GH releases - Add id-token: write permission at workflow and job level for OIDC
250a502 to
263bdbf
Compare
|
Before merging: configure npm trusted publishing (OIDC) for both packages on npmjs.com, otherwise the publish step will 403.
Optional: enable "Require 2FA and disallow tokens" on each package to lock publishing to OIDC-only. |
|
^ this is my task |
|
@rcdailey how did you determine the hashes for each of the GitHub actions? What would you recommend as a process moving forward for updating these? |
|
Hey thanks for the merge. To your question: In this case, I did |
Summary
Adds automated npm publishing to the release workflow for
@plannotator/opencodeand@plannotator/pi-extension, using npm's OIDC trusted publishing (no long-lived secrets required). Also adds CI smoke testing on pull requests and a manual dry-run trigger.What changed
The
release.ymlworkflow now has three trigger events and a newnpm-publishjob:Triggers
v*): Full release. Builds binaries, creates GitHub Release, and publishes both packages to npm with provenance attestations. This is the existing behavior plus npm publishing.main): Smoke test. Runs the full build pipeline and packs the npm packages without publishing. Catches build breakage before merge. Thereleasejob is skipped (no tag).workflow_dispatch): On-demand validation. Has a "dry run" checkbox (default: checked) that controls whether npm publish actually uploads. Useful for verifying the pipeline end-to-end.Dry-run logic
A workflow-level
DRY_RUNenv var is derived once and used everywhere:DRY_RUNfalsetruebun pm packonlytruebun pm packonlyfalsenpm publishing approach
bun publishdoes not yet support OIDC or provenance (oven-sh/bun#15601), so the job uses a two-step approach:bun pm packbuilds the tarball and resolvesworkspace:*referencesnpm publish *.tgz --provenance --access publicpublishes via OIDC with provenance attestationThis keeps the build on bun while using npm CLI for the publish step, which supports trusted publishing natively.
Other changes
id-token: writepermission added at workflow level for OIDCreleasejob gated at job level withif: startsWith(github.ref, 'refs/tags/')instead of always runningSetup required before first publish
Configure trusted publishers on npmjs.com
For each package (
@plannotator/opencodeand@plannotator/pi-extension):backnotpropplannotatorrelease.ymlFull instructions: npm trusted publishing docs
That's it
No
NPM_TOKENsecret or any other repository configuration is needed. OIDC trusted publishing uses short-lived tokens generated per workflow run, authenticated by GitHub's OIDC provider. Provenance attestations are generated automatically, giving consumers a verified link from the published package back to the source commit and workflow that built it (npm provenance docs).Testing
Validated on my fork (rcdailey/plannotator) using dry-run mode. Both packages pack successfully with correct contents and resolved workspace dependencies.